﻿#include "scheduler.h"

Scheduler::Scheduler(QWidget *parent)
    : QWidget(parent)
{
    table=TD_SCHEDULE;
    popup=nullptr;
    startReceiver();

    dbTry_failure=0;
    db=::sp_createStorage(DB_CONFIG);
    autoSync_timer=startTimer(AUTOSYNC_INTERVAL);
    dayNo=QDate::currentDate().dayOfWeek();
    updateTimeLine();
 //   ::sp_setStartup(true);
}

Scheduler::~Scheduler()
{
    recvThread.quit();
    recvThread.wait();
}

bool Scheduler::db_try()
{
    if(!db.isOpen())
    {
        if(!db.open())
        {
            dbTry_failure += 1;
            return false;
        }
        else
            return true;
    }
    else
        return true;
}

void Scheduler::startReceiver()
{
    receiver=new BaseReceiver(0,true,PORT_SCHEDULER);
    connect(receiver,&BaseReceiver::received,this,&Scheduler::received);
    connect(&recvThread,&QThread::finished,receiver,&QObject::deleteLater);
    receiver->moveToThread(&recvThread);
    recvThread.start();
}

void Scheduler::showPopup(const QString &detail, bool append)
{
    if(popup == nullptr)
        popup=new Popup(this);

    if(!popup->isVisible())
        popup->showMe(detail,append);
}

void Scheduler::received(const QByteArray &data)
{
    QString request=data;
    if(request == R_CMD_EXIT || request == QString(R_CMD_EXIT).toUpper())
    {
        qInfo() << QStringLiteral("收到退出指令，程序现在退出");
        qApp->quit();
    }
    else if(request == "pop")
        showPopup("POPUP TEST");
    else if(request == R_CMD_SYNC || request == QString(R_CMD_SYNC).toUpper())
    {
        qInfo() << QStringLiteral("收到同步指令，程序开始同步");
        updateTimeLine();
    }
}

void Scheduler::updateTimeLine()
{
    if(!db_try())
    {
        if(dbTry_failure > 4 && timeLine.size() < 1)
        {
            qWarning() << QStringLiteral("无法连接到数据库，timeLine数量为0，程序现在退出");
            qApp->quit();
        }
    }

    if(user.name == USER_NAME_UKN)
        return;

    if(!timeLine.isEmpty())
    {
        QMap<int,QTime>::const_iterator iter;
        for(iter=timeLine.constBegin();iter!=timeLine.constEnd();iter++)
        {
            int timerId=iter.key();
            killTimer(timerId);
        }
        timeLine.clear();
    }

    QSqlQuery query;
    query.exec(QString("select time from %1 where actor='%2' OR actor='%3' GROUP BY time")
               .arg(table)
               .arg(user.name)
               .arg(user.group));
    while (query.next()) {
        QTime time=query.value("time").toTime();
        if(time.isNull())
            continue;
        int secs=QTime::currentTime().secsTo(time);
        if(secs > 0)
        {
            int timerId=startTimer(secs * 1000);
            timeLine.insert(timerId,time);
        }
    }
    qInfo() << QStringLiteral("时间线已同步，当前数量：") + QString::number(timeLine.size());
    if(timeLine.isEmpty())
        qApp->quit();
}

void Scheduler::timerEvent(QTimerEvent *event)
{
    int id=event->timerId();
    if(timeLine.contains(id))
    {
        QString time=timeLine.value(id).toString("hh:mm:ss");
        timeLine.remove(id);
        killTimer(id);

        QSqlQuery query;
        query.exec(QString("select uid from %1 where time='%2'")
                   .arg(table)
                   .arg(time));

        QStringList actions;
        while (query.next()) {
            actions.append(query.value("uid").toString());
        }

        if(!actions.isEmpty())
            processActions(actions);

        if(timeLine.isEmpty())
            qApp->quit();
    }

    if(id == autoSync_timer)
        updateTimeLine();
}

void Scheduler::processActions(const QStringList actions)
{
    bool append=false;
    if(actions.size() > 1)
        append=true;

    foreach (QString uid, actions) {
        QSqlQuery query;
        query.exec(QString("select week,action,extra from %1 where uid='%2'").arg(table).arg(uid));
        while (query.next()) {
            int week=query.value("week").toInt();
            if(week != 0 && dayNo != week)
                return;

            int action=query.value("action").toInt();
            QString extra=query.value("extra").toString();
            switch (action) {
            case ACTION_REMIND:
                showPopup(extra,append);
                break;
            case ACTION_OPEN:
                QDesktopServices::openUrl(QUrl(extra));
                break;
            case ACTION_EXECUTE:
                QProcess::startDetached(extra);
                break;
            }
        }
    }
}
